﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ufida.u9.ait.openapi.utils;
using UFIDA.U9.Base;
using UFIDA.U9.CBO.FA.FA_AssetOwnerRelation;
using UFIDA.U9.FA.FA_AssetCardBE;
using UFIDA.U9.FA.FA_DisposalDocBE;
using UFIDA.U9.FA.FA_DisposalDocBP;
using UFIDA.U9.FA.FA_DisposalDocTypeBE;
using UFIDA.U9.FA.FA_Enum;
using UFSoft.UBF.Business;

namespace ufida.u9.ait.openapi
{
    internal class FADisposalBase
    {
        /// <summary>
        /// 资产处置单删除
        /// </summary>
        /// <param name="doc">资产处置实体</param>
        /// <returns>资产处置实体</returns>
        public static FADisposalDoc DeleteDoc(FADisposalDoc doc)
        {
            if (doc == null) return null;

            doc = doc.Key.GetEntity();
            if (!(doc.Status == AssetCardStatues.FAOpen
                || doc.Status== AssetCardStatues.Approving))
                throw new Exception($"单号:[{doc.DocNo}]状态不为开立或审核中,不能删除!");

            using(ISession session = Session.Open())
            {
                doc.Remove();
                session.Commit();
            }

            return doc;
        }
        /// <summary>
        /// 资产处置提交
        /// </summary>
        /// <param name="doc">资产处置实体</param>
        /// <returns>资产处置实体</returns>
        public static FADisposalDoc CommitDoc(FADisposalDoc doc)
        {
            if (doc.Status != AssetCardStatues.FAOpen)
                throw new Exception($"单号:[{doc.DocNo}]状态不为开立!");

            U9Utils.ClearCache();
            doc=doc.Key.GetEntity();
            DoSubmit bp = new DoSubmit();
            bp.DisposalDocSelectList = new List<DisposalDocBatchDTO>()
            {
                new DisposalDocBatchDTO()
                {
                    DisposalDocKey=doc.Key,
                    DocSysVersion=doc.SysVersion,
                }
            };
            List<UFIDA.U9.FA.FA_PropertyType.FABPReturnDTO> fABPReturnDTOs = bp.Do();
            return doc;
        }

        public static FADisposalDoc UnApproveDoc(FADisposalDoc doc)
        {
            if (doc.Status != AssetCardStatues.Approved)
                throw new Exception($"单号:[{doc.DocNo}]状态不为已审!");

            U9Utils.ClearCache();
            doc=doc.Key.GetEntity();
            DisApprove bp = new DisApprove();
            bp.DocList = new List<UFIDA.U9.FA.FA_CommonBP.DocActionParam>()
            {
                new UFIDA.U9.FA.FA_CommonBP.DocActionParam()
                {
                    DocKey=doc.Key,
                    DocSysVersion=doc.SysVersion,
                }
            };
            List<UFIDA.U9.FA.FA_PropertyType.FABPReturnDTO> fABPReturnDTOs = bp.Do();
            return doc;
        }
        /// <summary>
        /// 资产处置审核
        /// </summary>
        /// <param name="doc">资产处置实体</param>
        /// <returns>资产处置实体</returns>
        public static FADisposalDoc ApproveDoc(FADisposalDoc doc)
        {
            if (doc.Status == AssetCardStatues.Approved)
                throw new Exception($"单号:[{doc.DocNo}]状态为已审!");

            U9Utils.ClearCache();
            doc=doc.Key.GetEntity();
            DoApprove bp=new DoApprove();
            bp.DisposalDocSelectList = new List<DisposalDocBatchDTO>()
            {
                new DisposalDocBatchDTO()
                {
                    DisposalDocKey=doc.Key,
                    DocSysVersion=doc.SysVersion,
                }
            };
            List<UFIDA.U9.FA.FA_PropertyType.FABPReturnDTO> fABPReturnDTOs = bp.Do();

            return doc;
        }
        /// <summary>
        /// 资产处置单创建
        /// </summary>
        /// <param name="dto">DTO数据</param>
        /// <returns>资产处置单实体</returns>
        public static FADisposalDoc CreateDoc(FADisposalAITDTOData dto)
        {
            FADisposalDoc doc;
            using(ISession session = Session.Open())
            {
                //创建头
                doc = CreateHead(dto);
                //创建行
                CreateLines(dto, doc);

                //事务提交
                session.Commit();
            }
            return doc;
        }

        private static void CreateLines(FADisposalAITDTOData dto, FADisposalDoc doc)
        {
            if (dto.FA_DisposalDetail == null || dto.FA_DisposalDetail.Count == 0)
                throw new Exception("FA_DisposalDetail 必填");

            int rowno = 0;
            foreach(var linedto in dto.FA_DisposalDetail)
            {
                FA_DisposalDetail line = FA_DisposalDetail.Create(doc);
                rowno += 10;
                if (linedto.LineNum > 0)
                {
                    line.LineNum = linedto.LineNum;
                }
                else
                {
                    line.LineNum = rowno;
                }


                if (linedto.AssetCard == null) throw new Exception("行 资产卡片 必填");
                AssetCard card = EntityUtils.GetDocEntity<AssetCard>(linedto.AssetCard.Code);
                line.UOM = card.UOM;
                line.Qty = card.Qty;
                line.DisposalQty = linedto.DisposalQty;
                line.AssetCard = card;

                //资产处置变更单数据标签明细
                CreateTagDetail(linedto, line, card);

                //资产处置变更单预提折旧数据
                CreateDisposalDocPreDepreciateDetail(linedto, line, card);
            }
        }

        private static void CreateDisposalDocPreDepreciateDetail(FA_DisposalDetailAITDTOData linedto,FA_DisposalDetail line, AssetCard card)
        {
            FA_DisposalDocPreDepreciateDetail detail = FA_DisposalDocPreDepreciateDetail.Create(line);
            AssetCardAccountInformation accinfo = card.AssetAccountInfor[0];
            detail.AssetCard = card;
            detail.AssetCardAccountInformation = accinfo;
            detail.UsedLifeYear = accinfo.UsedLifeYear ;
            
            detail.LineNum = 10;
            detail.DPBook = accinfo.DpBook;
            detail.Currency= accinfo.Currency;
            detail.AccountingPeriod = EntityUtils.getPostPeriod(line.FADisposalDoc.BusinessDate);

            //金额处理
            detail.OriginalValue = accinfo.OriginalValue / card.Qty * linedto.DisposalQty;
            detail.NetValue = accinfo.NetValue / card.Qty * linedto.DisposalQty;

        }

        private static void CreateTagDetail(FA_DisposalDetailAITDTOData linedto, FA_DisposalDetail line, AssetCard card)
        {
            if (linedto.FA_DisposalTagDetail == null || linedto.FA_DisposalTagDetail.Count == 0)
                throw new Exception("FA_DisposalTagDetail 必填");

            int linenum = 0;
            foreach (var tagdto in linedto.FA_DisposalTagDetail)
            {
                FA_DisposalTagDetail detail = FA_DisposalTagDetail.Create(line);

                linenum += 10;
                detail.LineNum = linenum;
                detail.IsDisposal = true;
                detail.AssetCard = card;
                if (tagdto.AssetTag == null) throw new Exception("AssetTag 必填");
                detail.AssetTag = EntityUtils.GetEntityByCode<AssetTag>(tagdto.AssetTag.Code);
            }
        }

        private static FADisposalDoc CreateHead(FADisposalAITDTOData dto)
        {
            FADisposalDoc doc = FADisposalDoc.Create();

            doc.DocNo = "自动编号";
            if (string.IsNullOrEmpty(dto.BusinessDate)) throw new Exception("业务日期 必填");
            doc.BusinessDate = DateTime.Parse(dto.BusinessDate);
            if (dto.DocumentType == null) throw new Exception("单据类型 必填");
            doc.DocumentType = EntityUtils.GetEntityByCode<FA_DisposalDocType>(dto.DocumentType.Code);

            //组织
            doc.Org = Context.LoginOrg;
            doc.OwnerOrg = doc.Org;

            //其它
            doc.DisposalReson = dto.DisposalReson;
            //资产货主关系
            doc.AssetOwnerRelation = EntityUtils.GetAssetOwnerRelation();

            //资产处置变更单折旧账簿
            FADisposalDocDPBook book= FADisposalDocDPBook.Create(doc);
            book.LineNum = 10;
            book.DPBook = EntityUtils.GetDpBook();
            book.AffectDepreciatePeriod = EntityUtils.getPostPeriod(doc.BusinessDate);
            book.AccountingPeriod= book.AffectDepreciatePeriod;

            return doc;
        }
    }
}
